package com.ws.shop.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import com.ws.shop.bean.MailConfig;
import com.ws.shop.bean.SystemConfig;
import com.ws.shop.dao.SmtpDao;
import com.ws.shop.entity.MailAuth;
import com.ws.shop.entity.Member;
import com.ws.shop.entity.Smtp;
import com.ws.shop.service.SmtpService;
import com.ws.shop.util.DateUtil;
import com.ws.shop.util.SpringUtil;
import com.ws.shop.util.SystemConfigUtil;
import com.ws.shop.util.TemplateConfigUtil;

import freemarker.template.Configuration;
import freemarker.template.Template;
@Service(value="smtpService")
public class SmtpServiceImpl implements SmtpService,InitializingBean {
	private static Logger log = Logger.getLogger(SmtpServiceImpl.class);
	@Resource(name="smtpDao")
	private SmtpDao smtpDao;
	@Autowired
	private FreeMarkerConfigurer freemarkerManager;
	@Resource
	private JavaMailSender javaMailSender;
	@Resource
	private TaskExecutor taskExecutor;
	
	public static List<Smtp> systemSmtpList = new LinkedList<Smtp>();
	
	// 增加邮件发送任务
	public boolean addSendMailTask(final MimeMessage mimeMessage) {
		try {
			taskExecutor.execute(new Runnable() {
				public void run(){
					javaMailSender.send(mimeMessage);
				}
			});
			return true;
		} catch (Exception e) {
			log.error("发送邮件失败",e);
			return false;
		}
	}
	
	public static Smtp getRandomSenderMail(){
		if(systemSmtpList==null || systemSmtpList.size() == 0){
			return null;
		}else{
			Random random = new Random();
			int index = random.nextInt(systemSmtpList.size());
			Smtp smtp = systemSmtpList.get(index);
			return smtp;
		}
	}
	
	public boolean sendMail(String subject, String templateFilePath, Map<String, Object> data, String toMail) {
		try {
			Smtp smtp = getRandomSenderMail();
			if(smtp == null){
				log.error("邮件发送失败，未获取到系统邮件的服务器列表");
				return false;
			}
			SystemConfig systemConfig = SystemConfigUtil.getSystemConfig();
			JavaMailSenderImpl javaMailSenderImpl = (JavaMailSenderImpl)javaMailSender;
			javaMailSenderImpl.setHost(smtp.getSmtp());
			javaMailSenderImpl.setPort(smtp.getPort());
			javaMailSenderImpl.setUsername(smtp.getName());
			javaMailSenderImpl.setPassword(smtp.getPassword());
			MimeMessage mimeMessage = javaMailSenderImpl.createMimeMessage();
			Configuration configuration = freemarkerManager.getConfiguration();
			Template template = configuration.getTemplate(templateFilePath);
			String text = FreeMarkerTemplateUtils.processTemplateIntoString(template, data);
			MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false, "utf-8");
			mimeMessageHelper.setFrom(MimeUtility.encodeWord(systemConfig.getBeat_name())+ " <" + smtp.getName() + ">");
			mimeMessageHelper.setTo(toMail);
			mimeMessageHelper.setSubject(subject);
			mimeMessageHelper.setText(text, true);
			log.info("成功发送邮件："+smtp);
			return addSendMailTask(mimeMessage);
		} catch (Exception e) {
			log.error("邮件发送失败",e);
			return false;
		}
	}

	@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
	public List<Smtp> findSmtpListAll() {
		return smtpDao.findSmtpListAll();
	}

	@Transactional(rollbackFor=Exception.class)
	public void saveOrUpdate(Smtp smtp) {
		smtpDao.saveOrUpdate(smtp);
	}

	@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
	public Smtp loadById(int id) {
		return smtpDao.loadById(id);
	}

	@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
	public void reloadSmtp() {
		List<Smtp> list = smtpDao.getSystemSmtpList(1);
		if(list.size() > 0)
			systemSmtpList = list;
	}
	
	// 获取公共数据
	public Map<String, Object> getCommonData() {
		Map<String, Object> commonData = new HashMap<String, Object>();
		String base = SpringUtil.getServletContext().getContextPath();
		if(base.endsWith("/")){
			base = base.substring(0,base.length()-1);
		}
		commonData.put("base", base);
		commonData.put("systemConfig", SystemConfigUtil.getSystemConfig());
		commonData.put("time", DateUtil.dateToString(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS));
		return commonData;
	}

	public boolean sendResetPwdMail(Member member, int authType,String resetUrl) {
		Map<String, Object> data = getCommonData();
		data.put("title", MailAuth.ALL_AUTH_TYPE.get(authType));
		data.put("to", member.getRealname());
		data.put("resetUrl", resetUrl);
		MailConfig mailConfig = TemplateConfigUtil.getMailConfig(MailConfig.MAIL_SEND_RESET_PWD);
		String subject = mailConfig.getSubject();
		String templateFilePath = mailConfig.getTemplateFilePath();
		return sendMail(subject,templateFilePath,data,member.getMail());
	}

	public void afterPropertiesSet() throws Exception {
		reloadSmtp();
	}

}
